#ifndef _THREAD_H_
#define _THREAD_H_

#include <iostream>
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <vector>
#include <cstring> //strerror要包含的头文件
#include <string>
#include <functional>
#include "MyLog.hpp"

namespace MyThread
{
    using namespace MyLog; 
    static int num = 1;
    class Thread
    {
        using func_t = std::function<void()>; // 返回值为void，参数为空

    private:
        void SetRun()
        {
            _isrunning = true;
        }

        void SetDetach()
        {
            std::cout << "线程被分离" << std::endl;
            _isdetach = true;
        }

        static void *ThreadFunc(void *args)
        {
            Thread *self = static_cast<Thread *>(args);
            self->SetRun();      // 设置状态为run
            if (self->_isdetach) // 设置分离
                self->Detach();
            pthread_setname_np(self->_tid, self->_name.c_str()); //设置名字
            self->_func();  // 回调处理
            return nullptr; // 返回值不关心
        }

    public:
        Thread(func_t func)
            : _tid(0),
              _isdetach(false), 
              _isrunning(false),
              _ret(nullptr),
              _func(func)
        {
            _name = "new thread-" + std::to_string(num++);
        }

        void Detach()
        {
            if (_isdetach) // 如果已经分离了，直接返回
                return;
            if (_isrunning)           // 如果线程此时正在运行
                pthread_detach(_tid); // 分离线程
            // 如果此时还没运行，就只设置标志位，Start函数内会调用Detach
            SetDetach();
        }

        bool Start()
        {
            if (_isrunning)
                return false; // 线程已经启动了就不能重复启动
            int n = pthread_create(&_tid, nullptr, ThreadFunc, this);
            if (n != 0) // 创建失败
            {
                //std::cerr << "create tread error: " << strerror(n) << std::endl;
                return false;
            }
            else
            {
                //std::cout << _name << " create success" << std::endl;
            }
            return true;
        }

        bool Stop()
        {
            if (_isrunning)
            {
                int n = pthread_cancel(_tid);
                if (n != 0)
                {
                    std::cerr << "cancel tread error: " << strerror(n) << std::endl;
                    return false;
                }
                else
                {
                    _isrunning = false;
                    std::cout << _name << " stop success" << std::endl;
                }
            }
            return true;
        }

        bool Join()
        {
            if (_isdetach)
            {
                //std::cout << "线程已经被分离,join失败" << std::endl;
                return false;
            }
            int n = pthread_join(_tid, &_ret);
            if (n != 0)
            {
                //std::cerr << _name << "join tread error: " << strerror(n) << std::endl;
                LOG(LogLevel::DEBUG) << "join tread error: " << strerror(n);
                return false;
            }
            else
            {
                //std::cout << _name << " join success" << std::endl;
                LOG(LogLevel::DEBUG) << _name << " join success";
            }
            return true;
        }

        std::string GetName()
        {
            return _name;
        }

        ~Thread()
        {
        }

    private:
        pthread_t _tid;    // 线程ID
        std::string _name; // 线程的名字
        bool _isdetach;    // 线程是否设置分离状态
        bool _isrunning;   // 线程是否启动
        void *_ret;        // 线程等待的结果
        func_t _func;      // 线程执行的方法
    };
}

#endif